#include "bitmap.h"
#include "stdlib.h"
#include "stdio.h"

BitMap::BitMap()
{
}

void BitMap::initialize(char *bitmap, const int length)
{
    this->bitmap = bitmap;
    this->length = length;

    int bytes = ceil(length, 8);

    for (int i = 0; i < bytes; ++i)
    {
        bitmap[i] = 0;
    }
}

bool BitMap::get(const int index) const
{
    int pos = index / 8;
    int offset = index % 8;

    return (bitmap[pos] & (1 << offset));
}

void BitMap::set(const int index, const bool status)
{
    int pos = index / 8;
    int offset = index % 8;

    // 清0
    bitmap[pos] = bitmap[pos] & (~(1 << offset));

    // 置1
    if (status)
    {
        bitmap[pos] = bitmap[pos] | (1 << offset);
    }
}

int BitMap::allocate(const int count)
{
    int block[256]={0};
    int begin[256]={0};
    int tot=0;
    
    if (count == 0)
        return -1;

    int index, empty, start;
    index = 0;
    while (index < length)
    {
        //get(index)==1表示已经被占用
        while (index < length && get(index))		
            ++index;
	
	if (index==length) break;
	
        // 从当前开始寻找连续的资源
        empty = 0;
        start = index;
        while ((index < length) && (!get(index)) )
        {
            ++empty;
            ++index;
        }

	block[++tot]=empty;
	begin[tot]=start;
    }
   
    //First Fit
    for (int i=1;i<=tot;++i)
    	if (block[i]>=count)	{
    	    for (int j=0;j<count;++j)
    	    	set(begin[i]+j,1);
    	    return begin[i];
    	}

    return -1;
}

void BitMap::release(const int index, const int count)
{
    for (int i = 0; i < count; ++i)
    {
        set(index + i, false);
    }
}

char *BitMap::getBitmap()
{
    return (char *)bitmap;
}

int BitMap::size() const
{
    return length;
}
